import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.IOException;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Clip;
import javax.sound.sampled.UnsupportedAudioFileException;

public class SoundPlayer
{

    //define storage for start position
    Long nowFrame;
    Clip clip;

    // get the clip status
    String thestatus;

    AudioInputStream audioStream;
    static String thePath;

    private String[] files = null;

    private ArrayList<String> fileArray = new ArrayList<>();

    // initialize both the clip and streams
    public SoundPlayer()
            throws UnsupportedAudioFileException,
            IOException, LineUnavailableException
    {
        // the input stream object
        audioStream =
                AudioSystem.getAudioInputStream(
                        new File(thePath)
                                .getAbsoluteFile());

        // the reference to the clip
        clip = AudioSystem.getClip();

        clip.open(audioStream);

        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }

    public static void main(String[] args)
    {
        try
        {
            //add the path to the audio file
            // thePath = "C:\\Users\\22484\\Downloads\\JavaSoundDemo\\audio\\1-welcome.wav";

            SoundPlayer simpleSoundPlayer =
                    new SoundPlayer();

            String mediaPath = "D:\\Project";

            thePath = simpleSoundPlayer.loadJuke(mediaPath).get(0);

            simpleSoundPlayer.play();
            Scanner scanned = new Scanner(System.in);

            //show the options
            while (true)
            {
                System.out.println("1. 暂停");
                System.out.println("2. 恢复");
                System.out.println("3. 重新开始");
                System.out.println("4. 停止");
                System.out.println("5. 跳转到指定时间");
                int a = scanned.nextInt();
                simpleSoundPlayer.gotoChoice(a);
                if (a == 4)
                    break;
            }
            scanned.close();
        }

        catch (Exception e)
        {
            System.out.println("Experienced an error while playing sound.");
            e.printStackTrace();

        }
    }

    // operation is now as per the user's choice

    private void gotoChoice(int a)
            throws IOException, LineUnavailableException, UnsupportedAudioFileException
    {
        switch (a)
        {
            case 1:
                pause();
                break;
            case 2:
                resumeAudio();
                break;
            case 3:
                restart();
                break;
            case 4:
                stop();
                break;
            case 5:
                System.out.println("Selected time (" + 0 +
                        ", " + clip.getMicrosecondLength() + ")");
                Scanner scan = new Scanner(System.in);
                long cc = scan.nextLong();
                jump(cc);
                break;

        }

    }

    // play
    public void play()
    {
        //start the clip
        clip.start();

        thestatus = "play";
    }

    // Pause audio
    public void pause()
    {
        if (thestatus.equals("paused"))
        {
            System.out.println("audio is already paused");
            return;
        }
        this.nowFrame =
                this.clip.getMicrosecondPosition();
        clip.stop();
        thestatus = "paused";
    }

    // resume audio
    public void resumeAudio() throws UnsupportedAudioFileException,
            IOException, LineUnavailableException
    {
        if (thestatus.equals("play"))
        {
            System.out.println("The audio is"+
                    "being played");
            return;
        }
        clip.close();
        resetAudioStream();
        clip.setMicrosecondPosition(nowFrame);
        this.play();
    }

    // restart audio
    public void restart() throws IOException, LineUnavailableException,
            UnsupportedAudioFileException
    {
        clip.stop();
        clip.close();
        resetAudioStream();
        nowFrame = 0L;
        clip.setMicrosecondPosition(0);
        this.play();
    }

    // stop audio
    public void stop() throws UnsupportedAudioFileException,
            IOException, LineUnavailableException
    {
        nowFrame = 0L;
        clip.stop();
        clip.close();
    }

    // jump to a selected point
    public void jump(long a) throws UnsupportedAudioFileException, IOException,
            LineUnavailableException
    {
        if (a > 0 && a < clip.getMicrosecondLength())
        {
            clip.stop();
            clip.close();
            resetAudioStream();
            nowFrame = a;
            clip.setMicrosecondPosition(a);
            this.play();
        }
    }

    // reset the audio stream
    public void resetAudioStream() throws UnsupportedAudioFileException, IOException,
            LineUnavailableException
    {
        audioStream = AudioSystem.getAudioInputStream(
                new File(thePath).getAbsoluteFile());
        clip.open(audioStream);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }

    // 查找指定后缀文件
    public ArrayList<String> loadJuke(String name) {
        File file = new File(name);
        // 判断是否文件夹和空文件
        if (file != null && file.isDirectory()) {
            files = file.list();

            for (int i = 0; i < files.length; i++) {
                // 判断后缀 fileArray.add(files[i]);
                if (files[i].endsWith(".au") ||
                        files[i].endsWith(".rmf") ||
                        files[i].endsWith(".mid") ||
                        files[i].endsWith(".wav") ||
                        files[i].endsWith(".aif") ||
                        files[i].endsWith(".aiff")) {
                    fileArray.add(files[i]);
                }
                File leafFile = new File(file.getAbsolutePath(), files[i]);
                if (leafFile.isDirectory()) {

                    String[] list = leafFile.list();
                    for (int i1 = 0; i1 < list.length; i1++) {
                        // 判断后缀 fileArray.add(list[i1]);
                        if (list[i1].endsWith(".au") ||
                                list[i1].endsWith(".rmf") ||
                                list[i1].endsWith(".mid") ||
                                list[i1].endsWith(".wav") ||
                                list[i1].endsWith(".aif") ||
                                list[i1].endsWith(".aiff")) {
                            fileArray.add(list[i1]);
                        }
                    }
                }
            }
        }
        return fileArray;
    }

} 